package edu.fudan.webapp.action;

import com.opensymphony.xwork2.Preparable;
import org.apache.struts2.ServletActionContext;
import edu.fudan.Constants;
import edu.fudan.model.Role;
import edu.fudan.model.MeetingRoom;
import edu.fudan.model.BookMeetingRoom;
import edu.fudan.model.User;
import edu.fudan.webapp.util.RequestUtil;
import org.springframework.mail.MailException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Action for facilitating User Management feature.
 */
public class BookMeetingRoomAction extends BaseAction implements Preparable {
    private static final long serialVersionUID = 6776558938712115191L;
    private List<MeetingRoom> meetingRooms;
    private List<BookMeetingRoom> bookMeetingRooms;
    private BookMeetingRoom bookMeetingRoom;
    private MeetingRoom meetingRoom;
    private User user;
    private String id;
    private String meetingRoomId;
    private String query;
    
    /**
     * Holder for users to display on list screen
     *
     * @return list of users
     */
    public List<BookMeetingRoom> getBookMeetingRooms() {
        return bookMeetingRooms;
    }
    
    public List<MeetingRoom> getMeetingRooms() {
        return meetingRooms;
    }
    
    public void setMeetingRoomId(String meetingRoomId) {
        this.meetingRoomId = meetingRoomId;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public void setQ(String q) {
        this.query = q;
    }
    
    public BookMeetingRoom getBookMeetingRoom() {
        return bookMeetingRoom;
    }

    public void setBookMeetingRoom(BookMeetingRoom bookMeetingRoom) {
        this.bookMeetingRoom = bookMeetingRoom;
    }
    
    /**
     * Grab the entity from the database before populating with request parameters
     */
    public void prepare() {
        // prevent failures on new
    }

    /**
     * Delete the user passed in.
     *
     * @return success
     */
    public String delete() {
        bookMeetingRoomManager.removeBookMeetingRoom(bookMeetingRoom.getId().toString());
        List<Object> args = new ArrayList<Object>();
        args.add(bookMeetingRoom.getId());
        saveMessage(getText("bookMeetingRoom.deleted", args));
    
        return CANCEL;
    }

    /**
     * Grab the user from the database based on the "id" passed in.
     *
     * @return success if user found
     * @throws IOException can happen when sending a "forbidden" from response.sendError()
     */
    public String edit() throws IOException {
        HttpServletRequest request = getRequest();
        
        if (id != null) {
            // lookup the user using that id
            bookMeetingRoom = bookMeetingRoomManager.getBookMeetingRoom(id);
        } else {
            bookMeetingRoom = new BookMeetingRoom();
            meetingRoom = new MeetingRoom();
            meetingRoom.setId(new Long(meetingRoomId));
            user = userManager.getUserByUsername(request.getRemoteUser());
            bookMeetingRoom.setMeetingRoom(meetingRoom);
            bookMeetingRoom.setUser(user);
        }
        
        return SUCCESS;
    }

    /**
     * Default: just returns "success"
     *
     * @return "success"
     */
    public String execute() {
        return SUCCESS;
    }

    /**
     * Sends users to "mainMenu" when !from.equals("list"). Sends everyone else to "cancel"
     *
     * @return "mainMenu" or "cancel"
     */
    public String cancel() {
        if (!"list".equals(from)) {
            return "mainMenu";
        }
        return CANCEL;
    }

    /**
     * Save user
     *
     * @return success if everything worked, otherwise input
     * @throws Exception when setting "access denied" fails on response
     */
    public String save() throws Exception {
        HttpServletRequest request = getRequest();
        Integer originalVersion = bookMeetingRoom.getVersion();

        boolean isNew = ("".equals(getRequest().getParameter("bookMeetingRoom.version")));
        
        try {
            user = userManager.getUserByUsername(request.getRemoteUser());
            bookMeetingRoom.setUser(user);
            bookMeetingRoomManager.saveBookMeetingRoom(bookMeetingRoom);
        } catch (AccessDeniedException ade) {
            // thrown by UserSecurityAdvice configured in aop:advisor userManagerSecurity
            log.warn(ade.getMessage());
            getResponse().sendError(HttpServletResponse.SC_FORBIDDEN);
            return null;
        }
        
        if (!"list".equals(from)) {
            // add success messages
            saveMessage(getText("bookMeetingRoom.saved"));
            return "mainMenu";
        } else {
            // add success messages
            List<Object> args = new ArrayList<Object>();
            if (isNew) {
                saveMessage(getText("bookMeetingRoom.added"));
                return CANCEL;
            } else {
                saveMessage(getText("bookMeetingRoom.updated.byAdmin"));
                return CANCEL;
            }
        }
    }

    /**
     * Fetch all users from database and put into local "users" variable for retrieval in the UI.
     *
     * @return "success" if no exceptions thrown
     */
    public String list() {
    	if (!"meetingRoomList".equals(from)) {
    	    meetingRooms = meetingRoomManager.search(query);
    	} else {
    		bookMeetingRooms = bookMeetingRoomManager.getBookMeetingRooms(new Long(meetingRoomId));
        }
        return INPUT;
    }

}
